K I S S Technical notes Compiling Kiss -------------- There are basically three versions of Kiss: (a) one that includes readline support, (b) one that includes getline, and (b) one that contains neither. The versions are appropriately named "rkiss" (for readline), "gkiss" (for getline) and "bkiss" (for bare). The biggest executable is of course rkiss, since it includes editing and filename completion; the smallest is bkiss. I guess that for a SAR disk (see my Search-And-Rescue disk package on ftp.icce.rug.nl:/pub/unix/SAR*), you'd use the `getline' version or even the `bare' version; for reasons of space. Important note: All three versions are linked by the Makefile to use shared libraries. They are especially menat for SAR disks, where you have the libs anyway. If you want to make a Kiss for usage on your HDU (in emergencies, when the libs disappear or whatever), modify the Makefile to link with the `-static' flag and re-make. To compile: a. Edit the Makefile and adjust the macros at the top. If you have the readline libs, where do they reside? What is your BINDIR if you want to install the progs? b. Type "make rkiss" (readline), "make gkiss" (getline) or "make bkiss" (bare version). The executable file will then be "rkiss" or "gkiss" or "bkiss". Or just type "make all" to make all three. c. "make rinstall" will "make rkiss" and install it to $(BINDIR) (defined in the Makefile); "make binstall" will do the same for the bare version. A "make ginstall" will make gkiss and install it. You will need the following for a successful installation: - gcc better than 2.5.8 - libs 4.6.27 or better - libreadline.a and libtermcap.a if you want to make the readline version - bison and flex. You won't need the getline sources, I've included them in the archive of the sources (though I am not the author neither the maintainer). When you change the sources --------------------------- When you change the sources, please adher to the following: a. Always inform me if you have useful additions! Mail me at karel@icce.rug.nl. I'd like to have the latest version too! Also describe what you've changed, and why you've changed it -- instead of just mailing me some diffs. b. Edit the file "subversion.h" (read that as sub-version, not as revolution) and increment the number there. That will hopefully keep track of compilations. The versions are displayed with Kiss' "ver" command. Adding a built-in command ------------------------- This section describes how to create a built-in command, say "tar" (not that you would want to do that.. but whatever). Before you decide that you need it, please consider: a. Built-ins should be what you expect everyone to need in a rescue-disk environment. E.g., "ls". But not "loadkeys". b. Beware of promoting hardware-dependant stuff to built-ins. E.g., "e2fsck" may be what everyone uses, but I don't think that it should be a built-in command. 1. Making the command known to Kiss. Edit kiss.h and add a function declaration to the list of external functions. E.g., if you implement the "tar" command, then add a line extern int dotar (Stringstack s); to kiss.h. The function must return an integer (exit status) and must expect a Stringstack as its only argument. We'll get to Stringstacks later. Hint: enter the function name in alphabetical order, somewhere between the other doxxxx() declarations. Next, edit kiss.c and add to the table at the top: { "tar", dotar, 0 }, This table is used by the parser: when the string "tar" is seen, then dotar() will be called. The last field (0) means that dotar() can be called by a forked-off child process. A 1 in the last field means that the command is a `level zero' command, e.g., "setenv" is such a command: it must be handled by the parent Kiss and not by a child process. Generally, the built-in commands can be handled by children. Now edit dohelp.c (the "help" command) and add the description of your command to the list. It will then be shown when someone requests "help". Finally, edit the Makefile and add dotar.o to the list of objects. 2. Implementing your function. I strongly suggest that you implement your function dotar() in a file dotar.c (hence the name dotar.o added to the Makefile). That helps keeping the overview over what's where. Here's the start of your function, comments illustrate arguments etcetera: #include "kiss.h" /* all includes are in kiss.h, no need to request stdio.h etc. too */ int dotar (Stringstack s) /* function is called: dotar returns: an int (exit status), 0 if all is ok expects: a Stringstack, which holds two fields: nstr : number of stored strings (`argc' like counter) str : array of strings (`argv' like list) */ { /* now for some options parsing, e.g. -c -v -z -f will be recognized; also -h for help */ register int opt; while ( (opt = getopt (s.nstr, s.str, "cvzfh")) != -1 ) switch (opt) { case 'v': .... break; ... case 'h': default: error ("Bad commandline.\n" "Usage: %s [-cvzf] archive [file(s)]\n", progname); } .... } Implementation comments: - char *progname holds the `bare' program name, in your case "tar". Use it in printf()'s or whatever. Using the actual invocation name is better than hardwiring "tar" or whatever name; e.g., if you change the command name to "mytar" in kiss.c then "mytar" will show up as "progname" in your displayed messages. - s.nstr and s.str hold the arguments, like argc/argv - Use getopt() and optind to parse the flag arguments. See the manpages. Always enable a `-h' flag, which with the `default' case, shows help. - Use the function error() to show error messages and terminate; it works just like printf() but prints "program: " first. - Use warning() to show warnings, works like error() but doesn't terminate. If you need auxiliary functions to your dotar() function, you can either make them statics in dotar.c or declare them in kiss.h and implement them in separate source files. In the latter case you'd of course need to add the names of those files to the Makefile. If you want to see a small example, check out dotouch.c which implements the "touch" command. It's about the smallest thing that I can think of.